/*
 * Copyright (C) 2017-2021
 * All rights reserved, Designed By
 * Copyright authorization contact 18814114118
 */
package com.shop.cereshop.admin.service.buyer.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.shop.cereshop.admin.dao.buyer.CereBuyerUserDAO;
import com.shop.cereshop.admin.dao.credit.CereCreditRecordDAO;
import com.shop.cereshop.admin.dao.disable.BuyerDisableTimeDAO;
import com.shop.cereshop.admin.dao.history.CereWebHistoryDAO;
import com.shop.cereshop.admin.page.buyer.BuyerUser;
import com.shop.cereshop.admin.page.buyer.BuyerUserDetail;
import com.shop.cereshop.admin.page.user.BuyerUsersVO;
import com.shop.cereshop.admin.page.wallet.TransactionVO;
import com.shop.cereshop.admin.param.buyer.*;
import com.shop.cereshop.admin.param.credit.UpdateCreditParam;
import com.shop.cereshop.admin.param.user.UserSearchParam;
import com.shop.cereshop.admin.service.buyer.CereBuyerUserService;
import com.shop.cereshop.admin.service.history.impl.CereWebHistoryServiceImpl;
import com.shop.cereshop.admin.service.label.CereBuyerLabelService;
import com.shop.cereshop.admin.service.log.CerePlatformLogService;
import com.shop.cereshop.admin.utils.EncodeUtil;
import com.shop.cereshop.commons.cache.constants.CacheKeyConstants;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.constant.CreditOptTypeEnum;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.domain.buyer.CereBuyerReceive;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import com.shop.cereshop.commons.domain.common.Page;
import com.shop.cereshop.commons.domain.common.PageParam;
import com.shop.cereshop.commons.domain.credit.CereCreditRecord;
import com.shop.cereshop.commons.domain.disable.BuyerDisableTime;
import com.shop.cereshop.commons.domain.label.CereBuyerLabel;
import com.shop.cereshop.commons.domain.label.CerePlatformLabel;
import com.shop.cereshop.commons.domain.user.CerePlatformUser;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.tencent.im.enums.im.ImStatus;
import com.shop.cereshop.commons.tencent.im.model.response.SendMsgResponse;
import com.shop.cereshop.commons.tencent.im.service.TimMsgService;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.EncryptUtil;
import com.shop.cereshop.commons.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;
@Slf4j
@Service
public class CereBuyerUserServiceImpl implements CereBuyerUserService {

    @Autowired
    private CereBuyerUserDAO cereBuyerUserDAO;

    @Autowired
    private CereBuyerLabelService cereBuyerLabelService;

    @Autowired
    private CerePlatformLogService cerePlatformLogService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private CereCreditRecordDAO cereCreditRecordDAO;

    @Autowired
    private EncodeUtil encodeUtil;

    @Autowired
    private BuyerDisableTimeDAO buyerDisableTimeDAO;

    @Autowired
    private TimMsgService timMsgService;
    @Autowired
    private CereWebHistoryDAO cereWebHistoryDAO;

    @Autowired

    private CereWebHistoryServiceImpl cereWebHistoryService;



    @Override
    public Page<BuyerUser> getAll(BuyerGetAllParam param) throws CoBusinessException {
        if (param.getPage() != null && param.getPageSize() != null) {
            PageHelper.startPage(param.getPage(), param.getPageSize());
        }
        long start = System.currentTimeMillis();
        log.info("start " + start);
        List<BuyerUser> list = cereBuyerUserDAO.getAll(param);
        log.info("end " + (System.currentTimeMillis() - start));
        for (BuyerUser user : list) {
            List<Long> labelIds = cereBuyerLabelService.findByBuyerUserId(user.getBuyerUserId());
            user.setLabelIds(labelIds);
            user.setPhone(encodeUtil.encodePhone(user.getPhone()));
            user.setName(encodeUtil.encodeInfo(user.getName()));
        }
        PageInfo<BuyerUser> pageInfo = new PageInfo<>(list);
        Page<BuyerUser> page = new Page(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public BuyerUserDetail getById(BuyerGetByIdParam param) throws CoBusinessException {
        //查询客户数据
        BuyerUserDetail detail = cereBuyerUserDAO.getById(param.getBuyerUserId());
        if (detail != null) {
            detail.setName(encodeUtil.encodeInfo(detail.getName()));
            detail.setPhone(encodeUtil.encodePhone(detail.getPhone()));
            //查询用户标签数据
            detail.setLabels(cereBuyerUserDAO.findLabels(param.getBuyerUserId()));
            //查询标签id
            detail.setLabelIds(cereBuyerLabelService.findByBuyerUserId(detail.getBuyerUserId()));
            //查询下单数
            detail.setOrders(cereBuyerUserDAO.findOrders(param.getBuyerUserId()));
            //查询支付成功数
            detail.setPays(cereBuyerUserDAO.findPays(param.getBuyerUserId()));
            //查询购买商品数
            detail.setProducts(cereBuyerUserDAO.findProducts(param.getBuyerUserId()));
            //查询累计消费额
            detail.setPrice(cereBuyerUserDAO.findPrice(param.getBuyerUserId()));
            //查询售后次数
            detail.setAfters(cereBuyerUserDAO.findAfters(param.getBuyerUserId()));
            //查询售后单数
            detail.setAfterOrders(cereBuyerUserDAO.findAfterOrders(param.getBuyerUserId()));
            //查询售后成功单数
            detail.setSuccessAfters(cereBuyerUserDAO.findSuccessAfters(param.getBuyerUserId()));
            //查询订单列表
            detail.setOrderList(cereBuyerUserDAO.findOrderList(param));
            //查询评论列表
            detail.setComments(cereBuyerUserDAO.findComments(param.getBuyerUserId()));
            //查询收货地址列表
            List<CereBuyerReceive> receiveList = cereBuyerUserDAO.findReceives(param.getBuyerUserId());
            for (CereBuyerReceive receive : receiveList) {
                receive.setReceivePhone(encodeUtil.encodePhone(receive.getReceivePhone()));
                receive.setReceiveName(encodeUtil.encodeInfo(receive.getReceiveName()));
                receive.setReceiveAdress(encodeUtil.encodeInfo(receive.getReceiveAdress()));
                receive.setAddress(encodeUtil.encodeInfo(receive.getAddress()));
            }
            detail.setReceives(receiveList);
        }
        return detail;
    }

    @Override
    public List<CerePlatformLabel> getLabels(BuyerGetLabelsParam param) throws CoBusinessException {
        return cereBuyerUserDAO.getLabels(param);
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void saveUserLabel(BuyerSaveUserLabelParam param, CerePlatformUser user) throws CoBusinessException {
        String time = TimeUtils.yyMMddHHmmss();
        if (!EmptyUtils.isEmpty(param.getBuyerLabelIds())) {
            //查询客户已有标签的
            List<Long> ids = cereBuyerLabelService.findAlreadyByUser(param);
            if (!EmptyUtils.isEmpty(ids)) {
                //过滤已有标签
                for (int i = 0; i < param.getBuyerLabelIds().size(); i++) {
                    if (ids.contains(param.getBuyerLabelIds().get(i))) {
                        param.getBuyerLabelIds().remove(i);
                        i--;
                    }
                }
            }
            if (!EmptyUtils.isEmpty(param.getBuyerLabelIds())) {
                for (Long id : param.getBuyerLabelIds()) {
                    CereBuyerLabel cereBuyerLabel = new CereBuyerLabel();
                    cereBuyerLabel.setBuyerUserId(param.getBuyerUserId());
                    cereBuyerLabel.setBuyerLabelId(id);
                    cereBuyerLabelService.insert(cereBuyerLabel);
                    //新增日志
                    cerePlatformLogService.addLog(user, "客户管理", "平台端操作", "贴标签", String.valueOf(cereBuyerLabel.getBuyerUserId()), time);
                }
            }
        }
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void blacklist(BuyerBlackListParam param, CerePlatformUser user) throws CoBusinessException {
        String time = TimeUtils.yyMMddHHmmss();
        String describe = "";
        CereBuyerUser cereBuyerUser = new CereBuyerUser();
        cereBuyerUser.setBuyerUserId(param.getBuyerUserId());
        cereBuyerUser.setIfBlack(param.getIfBlack());
        cereBuyerUser.setUpdateTime(time);
        cereBuyerUserDAO.updateByPrimaryKeySelective(cereBuyerUser);
        if (IntegerEnum.YES.getCode().equals(param.getIfBlack())) {
            //加入黑名单
            describe = "加入黑名单";
        } else {
            //取消黑名单
            describe = "取消黑名单";
        }
        //新增日志
        cerePlatformLogService.addLog(user, "客户管理", "平台端操作", describe, String.valueOf(param.getBuyerUserId()), time);
    }

    @Override
    public List<CerePlatformLabel> getUserLabels(BuyerGetLabelsParam param) throws CoBusinessException {
        return cereBuyerUserDAO.getUserLabels(param);
    }

    @Override
    @Transactional
    public void updateCredit(UpdateCreditParam param, CerePlatformUser user) throws CoBusinessException {
        //定义加锁key
        String key = CacheKeyConstants.CREDIT_LOCK + param.getBuyerUserId();
        //加锁
        RLock redissonLock = redissonClient.getLock(key);
        String time = TimeUtils.yyMMddHHmmss();
        long buyerUserId = param.getBuyerUserId();
        Integer credit = param.getCredit();
        if (credit == 0) {
            return;
        }
        Integer absCredit = Math.abs(param.getCredit());
        boolean notEnoughCredit = false;
        try {
            redissonLock.lock();
            CereBuyerUser buyerUser = cereBuyerUserDAO.selectById(buyerUserId);
            if (credit < 0 && buyerUser.getCredit() < absCredit) {
                notEnoughCredit = true;
            } else {
                CreditOptTypeEnum typeEnum = CreditOptTypeEnum.ADMIN_ADD;
                String describe = "增加" + absCredit + "积分";
                if (credit < 0) {
                    typeEnum = CreditOptTypeEnum.ADMIN_SUB;
                    describe = "扣减" + absCredit + "积分";
                }
                cereBuyerUserDAO.increaseCredit(buyerUserId, param.getCredit());
                //增加积分记录
                CereCreditRecord record = CreditOptTypeEnum.initRecord(typeEnum);
                record.setBuyerUserId(buyerUserId);
                record.setCreateTime(time);
                record.setUpdateTime(time);
                record.setCredit(absCredit);
                record.setRemainCredit(buyerUser.getCredit() + credit);
                cereCreditRecordDAO.insert(record);
                //新增日志
                cerePlatformLogService.addLog(user, "客户管理", "平台端操作", describe, String.valueOf(param.getBuyerUserId()), time);
            }
        } catch (Exception e) {
            log.error("increaseCredit fail: buyerUserId = {}, credit = {}" + e.getMessage(),
                    buyerUserId, credit, e);
        } finally {
            redissonLock.unlock();
        }
        if (notEnoughCredit) {
            throw new CoBusinessException(CoReturnFormat.CREDIT_NOT_ENOUGH);
        }
    }

    @Override
    public Page<CereBuyerUser> searchUser(UserSearchParam param) {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        LambdaQueryWrapper<CereBuyerUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CereBuyerUser::getBuyerUserId, param.getSearchKey())
                .or()
                .eq(CereBuyerUser::getWechatOpenId, param.getSearchKey())
                .or()
                .like(CereBuyerUser::getName, param.getSearchKey())
                .or()
                .eq(CereBuyerUser::getPhone, param.getSearchKey());
        List<CereBuyerUser> userList = cereBuyerUserDAO.selectList(wrapper);
        PageInfo<CereBuyerUser> pageInfo = new PageInfo<>(userList);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public Page<CereBuyerUser> selectUserInfo(PageParam pageParam) {
        PageHelper.startPage(pageParam.getPage(), pageParam.getPageSize());
        List<CereBuyerUser> userList = cereBuyerUserDAO.selectUserInfo();
        PageInfo<CereBuyerUser> pageInfo = new PageInfo<>(userList);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());

        return page;
    }

    @Override
    public Page<BuyerUsersVO> getAllUser(BuyerGetUsersParam param) {
        //设置分页参数
        PageHelper.startPage(param.getPage(), param.getPageSize());
        System.out.println(param.getState());
        List<BuyerUsersVO> list = cereBuyerUserDAO.getAllUser(param);
        //对手机号进行加密
        for (BuyerUsersVO vo : list) {
            vo.setPhone(encodeUtil.encodePhone(vo.getPhone()));
//           脱敏用户id
            vo.setBuyerUserIdMask(encodeUtil.encodeInfo(String.valueOf(vo.getBuyerUserId())));
//            脱敏用户昵称
            vo.setName(encodeUtil.encodeInfo(vo.getName()));

//            脱敏用户账号
            vo.setAccount(encodeUtil.encodeInfo(vo.getAccount()));

        }
        PageInfo<BuyerUsersVO> pageInfo = new PageInfo<>(list);
        Page<BuyerUsersVO> result = new Page<>(pageInfo.getList(), pageInfo.getTotal());
        return result;
    }

    @Override
    @Transactional
    public void updateAccount(BuyerGetUsersParam param,HttpServletRequest request) throws CoBusinessException {

        String action="";
        String result="";

        CerePlatformUser  plateformUser  =(CerePlatformUser)request.getAttribute("user");
        System.out.println(plateformUser);

        //先查询用户当前启用状态
        CereBuyerUser user = null;
        if (param.getBuyerUserId() != null) {
            user = cereBuyerUserDAO.selectById(param.getBuyerUserId());
        }

        LocalDateTime banTime = param.getBanTime();
        //判断入参状态
        if (user != null) {
            if (param.getState() == 1) {
                if (user.getState().equals(param.getState())) {
                    throw new CoBusinessException(CoReturnFormat.FAIL);
                }
                LambdaQueryWrapper<CereBuyerUser> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(CereBuyerUser::getBuyerUserId, param.getBuyerUserId());
                user.setState(1);
//                更改用户封禁状态
                int update = cereBuyerUserDAO.update(user, queryWrapper);
//                删除用户封禁时间
                int number = buyerDisableTimeDAO.deleteByBuyerId(param.getBuyerUserId());

                if (number<=0){
                    throw new CoBusinessException(CoReturnFormat.FAIL);
                }
            } else {

                LocalDateTime now = LocalDateTime.now();
                BuyerDisableTime buyerDisableTime = new BuyerDisableTime();
                buyerDisableTime.setBuyerId(param.getBuyerUserId());
                buyerDisableTime.setCreatTime(now);
                buyerDisableTime.setDisableTime(banTime);
//        向数据库中插入封禁时间
                int insert = buyerDisableTimeDAO.insert(buyerDisableTime);

              action= plateformUser.getName()+"封禁了"+"用户id为"+param.getBuyerUserId()+"的用户";

                if (insert>0){
                    result= "成功";
                }
                else {
                    result= "失败";
                }
                cereWebHistoryService.addHistory(plateformUser.getPlatformUserId(),plateformUser .getName(),plateformUser.getPhone(),plateformUser.getAvatar()==null ?null:plateformUser.getAvatar(),action,result,1);


                if (insert <= 0) {
                    throw new CoBusinessException(CoReturnFormat.FAIL);
                }

                LambdaQueryWrapper<CereBuyerUser> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(CereBuyerUser::getBuyerUserId, param.getBuyerUserId());
                user.setState(0);
                cereBuyerUserDAO.update(user, queryWrapper);
            }
        } else {
            throw new CoBusinessException(CoReturnFormat.USER_NOT_EXIST);
        }
    }

    @Override
    public TransactionVO getTransaction(BuyerGetUsersParam param) {
        return cereBuyerUserDAO.getTransaction(param);
    }

    @Override
    public CereBuyerUser getByUserId(Long buyerUserId) {
        return cereBuyerUserDAO.getByUserId(buyerUserId);
    }

    @Override
    public List<BuyerUsersVO> getAllUserToList() {
        BuyerGetUsersParam buyerGetUsersParam = new BuyerGetUsersParam();
        List<BuyerUsersVO> list = cereBuyerUserDAO.getAllUser(buyerGetUsersParam);
        return list;

    }

    @Override
    public Page<CereBuyerUser> getUserBaseeInfo(BuyerBaseUserInfo buyerBaseUserInfo) {
//        分页查询用户基本信息
        PageHelper.startPage(buyerBaseUserInfo.getPage(), buyerBaseUserInfo.getPageSize());
        if (buyerBaseUserInfo.getUserAccount() != null) {
            buyerBaseUserInfo.setUserAccountNum(Long.valueOf(buyerBaseUserInfo.getUserAccount()));
        }
        List<CereBuyerUser> list = cereBuyerUserDAO.selectUserBaseInfo(buyerBaseUserInfo);
//        根据分页获取到的用户id对手机号进行解密
        for (CereBuyerUser user : list) {
            user.setPassword(EncryptUtil.decrypt(user.getPassword()));
            if (user.getAuthStatus() == null) {
                user.setAuthStatus(0);
            }
//            对用户id进行脱敏
//            user.setBuyerUserIdMask(encodeUtil.encodeInfo(String.valueOf(user.getBuyerUserId())));
//            对用户昵称进行脱敏
            user.setName(encodeUtil.encodeInfo(user.getName()));
//            对用户手机号进行脱敏
            user.setPhone(encodeUtil.encodePhone(user.getPhone()));
//            对用户密码进行脱敏
            user.setPassword(encodeUtil.encodeInfo(user.getPassword()));
//            对用户账号进行脱敏
            user.setUserAccount(encodeUtil.encodeInfo(user.getUserAccount()));
        }
        PageInfo<CereBuyerUser> pageInfo = new PageInfo<>(list);
        Page<CereBuyerUser> page = new Page<>(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public Integer updateUserBaseInfo(CereBuyerUser cereBuyerUser,HttpServletRequest request) {

        String result="";
        String action="";
        CerePlatformUser  user  =(CerePlatformUser)request.getAttribute("user");


//        对修改密码进行加密处理
        System.out.println(cereBuyerUser.getPassword());
        cereBuyerUser.setPassword(EncryptUtil.encrypt(cereBuyerUser.getPassword()));
//        TimMsgService
        Integer number = cereBuyerUserDAO.updateUserBaseInfo(cereBuyerUser);

        if (number>0){
          result ="成功";
        }
        else {
            result= "失败";
        }
           action= user.getName()+"修改"+"用户id为"+cereBuyerUser.getBuyerUserId()+"的用户信息";

        cereWebHistoryService.addHistory(user.getPlatformUserId(),user.getName(),user.getPhone(),user.getAvatar()==null ?null:user.getAvatar(),action,result,1);

        return number;

    }

    @Override
    @Transactional
    public Integer updateTrends(BuyerTrendsParam param,HttpServletRequest request) {
        String action="";
        String result="";
        Integer number = cereBuyerUserDAO.updateTrends(param);
        CerePlatformUser  user  =(CerePlatformUser)request.getAttribute("user");
        if (number>0){
            result ="成功";
        }
        else {
            result= "失败";
        }
        if (param.getState()==1){
            action= user.getName()+"解禁了"+"用户id为"+param.getBuyerUserId()+"发布动态功能";
        }else if (param.getState()==0){
           action= user.getName()+"封禁了"+"用户id为"+param.getBuyerUserId()+"发布动态功能";
        }
        cereWebHistoryService.addHistory(user.getPlatformUserId(),user.getName(),user.getPhone(),user.getAvatar()==null ?null:user.getAvatar(),action,result,1);
        return number ;

    }

    @Override
    @Transactional
    public Integer updateIm(BuyerImParam param,HttpServletRequest  request) throws CoBusinessException {
        String result = "";
        String action = "";
        CerePlatformUser  user  =(CerePlatformUser)request.getAttribute("user");
        SendMsgResponse sendMsgResponse =null;
        if (param.getStatus() == 1){
            sendMsgResponse= timMsgService.sendDisableUserImNotice(param.getBuyerUserId(), ImStatus.ON.getStatus());

            if (sendMsgResponse.getErrorCode()==0){
                result= "成功";
            }
            else {
                result="失败";
            }

                action=user.getName()+"解禁了"+"用户id为"+param.getBuyerUserId()+"IM的功能";

            cereWebHistoryService.addHistory(user.getPlatformUserId(),user.getName(),user.getPhone(),user.getAvatar()==null ?null:user.getAvatar(),action,result,1);
        }
        else {
            sendMsgResponse= timMsgService.sendDisableUserImNotice(param.getBuyerUserId(),ImStatus.OFF.getStatus());

            if (sendMsgResponse.getErrorCode()==0){
                result= "成功";
            }
            else {
                result= "失败";
            }
           action =user.getName()+"封禁了"+"用户id为"+param.getBuyerUserId()+"IM的功能";

        }
        cereWebHistoryService.addHistory(user.getPlatformUserId(),user.getName(),user.getPhone(),user.getAvatar()==null ?null:user.getAvatar(),action,result,1);
            Integer number = cereBuyerUserDAO.updateIm(param);

        if (!sendMsgResponse.getActionStatus().equals("OK")) {
            throw new CoBusinessException(CoReturnFormat.FAIL);
        }
        return number;
    }

    @Override
    @Transactional
    public Integer updateOther(BuyerOtherParam param, HttpServletRequest request) {
        Integer number = cereBuyerUserDAO.updateOther(param);

       String result="";
       String action="";
        CerePlatformUser  user  =(CerePlatformUser)request.getAttribute("user");
        if (number>0){
            result="成功";
        }
        else {
           result="失败";
        }
        if (param.getStatus()==1){
           action=user.getName()+"解禁了"+"用户id为"+param.getBuyerUserId()+"点赞,收藏,关注功能";
        }else if (param.getStatus()==0){
            action=user.getName()+"封禁了"+"用户id为"+param.getBuyerUserId()+"点赞,收藏,关注功能";
        }
        cereWebHistoryService.addHistory(user.getPlatformUserId(),user.getName(),user.getPhone(),user.getAvatar()==null ?null:user.getAvatar(),action,result,1);
        return number;
    }


}
